package com.ruoyi.depot.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.ruoyi.commodity.domain.ProductImage;
import com.ruoyi.commodity.mapper.ProductImageMapper;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.depot.domain.DTOReceiptProducts;
import com.ruoyi.depot.domain.InboundProducts;
import com.ruoyi.depot.domain.ProcuredStorage;
import com.ruoyi.depot.domain.vo.SelectedOrderVO;
import com.ruoyi.depot.domain.vo.VoOrdersProduct;
import com.ruoyi.depot.domain.vo.VoOrdersTime;
import com.ruoyi.depot.mapper.ProcuredStorageMapper;
import com.ruoyi.depot.mapper.VoOrdersProductMapper;
import com.ruoyi.depot.service.VoOrdersProductService;
import com.ruoyi.procured.mapper.ProcuredOrdersMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.NumberUtils;


import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
public class VoOrdersProductServiceImpl implements VoOrdersProductService {

    @Autowired
    VoOrdersProductMapper voOrdersProductMapper;

    @Autowired
    ProcuredStorageMapper procuredStorageMapper;

    @Autowired
    ProcuredOrdersMapper procuredOrdersMapper;

    @Autowired
    ProductImageMapper productImageMapper;

    @Override
    public List<VoOrdersProduct> selectVoOrdersProductByOrdersId(VoOrdersProduct voOrdersProduct) {
        return voOrdersProductMapper.selectVoOrdersProductByOrdersId(voOrdersProduct);
    }

    @Override
    public List<VoOrdersProduct> selectVoOrdersProductByOrderId(VoOrdersProduct voOrdersProduct) {
        Long [] receiptProductIds = voOrdersProduct.getReceiptProductIds();
        Long [] ordersProductIds = voOrdersProduct.getOrdersProductIds();
        List<VoOrdersProduct> ordersProductList= new ArrayList<VoOrdersProduct>();
        //修改收货单，选中的商品
        if((StringUtils.isNotNull(receiptProductIds)&&receiptProductIds.length>0)){
            List<VoOrdersProduct> HaveReceiptProductsList= voOrdersProductMapper.selectHaveReceiptProductsListBYId(voOrdersProduct, ordersProductIds, receiptProductIds);
            ordersProductList.addAll(HaveReceiptProductsList);
            //修改收货单，无商品
        }else if(StringUtils.isNull(receiptProductIds)&&StringUtils.isNotNull(voOrdersProduct.getReceiptId())){
            List<VoOrdersProduct> HaveReceiptProductsList= voOrdersProductMapper.selectHaveReceiptProductsListBYReceiptId(voOrdersProduct, ordersProductIds);
            ordersProductList.addAll(HaveReceiptProductsList);
        }else{
            List<VoOrdersProduct> voOrdersProductList= voOrdersProductMapper.selectVoOrdersProductByOrderId(voOrdersProduct, ordersProductIds);
            ordersProductList.addAll(voOrdersProductList);
        }
        // 提取所有的产品id
        List<Long> productIds = ordersProductList.stream().map(VoOrdersProduct::getProductId).collect(Collectors.toList());

        if(!productIds.isEmpty()){
            // 查询所有产品图片
            List<ProductImage> productImages = productImageMapper.selectProductImagesByProductId(productIds);

            // 按照产品id进行分组对应的图片
            Map<Integer, List<String>> groupedImageUrls = productImages.stream()
                    .collect(Collectors.groupingBy(
                            ProductImage::getProductId,
                            Collectors.mapping(
                                    ProductImage::getProductImagePath,
                                    Collectors.toList()
                            )
                    ));

            // 分装对应的产品图片
            ordersProductList.forEach(
                    a -> {
                        a.setImgName(groupedImageUrls.get(a.getProductId().intValue()));
                    }
            );
        }
        return ordersProductList;
    }

    @Override
    public List<VoOrdersProduct> selectVoOrdersProductByProductId(VoOrdersProduct voOrdersProduct) {
        String[] array  = voOrdersProduct.getIds();
        voOrdersProduct.setIds(converter(array));
        List<VoOrdersProduct> list = voOrdersProductMapper.selectVoOrdersProductByProductId(voOrdersProduct);
        voOrdersProduct.setSelectedStatus(Constants.FAIL);
        voOrdersProductMapper.updateVoOrdersProductBySelectedStatus(voOrdersProduct.getIds(), voOrdersProduct.getSelectedStatus());
        return list;
    }

    @Override
    public int cancelPutAway(List<VoOrdersProduct> voOrdersProductList) {
        VoOrdersProduct voOrdersProduct = new VoOrdersProduct();
        for (VoOrdersProduct voOrdersProduct1:voOrdersProductList) {
            if(voOrdersProduct1.getFlay()){
                voOrdersProduct.setSelectedStatus(Constants.SUCCESS);
            }
        }
        /*String[] array = new String[0];
        List<String> arrayList = new ArrayList<>(); // 创建一个 ArrayList
        for (VoOrdersProduct newVoOrdersProduct: voOrdersProductList) {
            String id = newVoOrdersProduct.getId();
            String[] splitArray = id.split(","); // 每次循环中获得的分割结果
            arrayList.addAll(Arrays.asList(splitArray)); // 将分割结果添加到 ArrayList
        }
        array = arrayList.toArray(new String[0]); // 将 ArrayList 转换为数组*/

        String[] array = voOrdersProductList.stream()  // 使用 Stream 对 voOrdersProductList 进行处理
                .map(VoOrdersProduct::getId)  // 提取每个 VoOrdersProduct 对象的 id 字段
                .flatMap(id -> Arrays.stream(id.split(",")))  // 将 id 字符串分割并展开为单个元素的 Stream
                .toArray(String[]::new);  // 将 Stream 转换为 String[] 数组
        voOrdersProduct.setIds(array);
        return voOrdersProductMapper.updateVoOrdersProductBySelectedStatus(voOrdersProduct.getIds() ,voOrdersProduct.getSelectedStatus());
    }

    @Override
    public int addInboundProducts(String nickName,VoOrdersProduct voOrdersProduct) {
        AtomicInteger index = new AtomicInteger(0);
        List<ProcuredStorage> collect = procuredOrdersMapper.selectByOrdersId(voOrdersProduct.getOrdersIds()).stream()
                .map(ProcuredOrders -> {
                    final Long[] sum = {Long.valueOf(0)};
                    ProcuredStorage procuredStorage = new ProcuredStorage();
                    List<InboundProducts> newCollect = voOrdersProduct.getVoOrdersProductList().stream()
                            .filter(VoOrdersProduct -> {
                                String ordersId = VoOrdersProduct.getOrdersId();
                                String[] ids = ordersId.split(", ");
                                long[] longIds = Arrays.stream(ids)
                                        .mapToLong(Long::parseLong)
                                        .toArray();
                                return Arrays.stream(longIds)
                                        .anyMatch(id -> id == ProcuredOrders.getOrdersId());
                            })
                            .map(VoOrdersProduct -> {
                                InboundProducts inboundProducts = new InboundProducts();
                                String id = VoOrdersProduct.getId();
                                String[] ids = id.split(",");
                                List<String> numbers = new ArrayList<>(Arrays.asList(ids));
                                List<VoOrdersTime> voOrdersTimeList = new ArrayList<>();
                                for (int i = 0;i<numbers.size();i++){
                                    voOrdersTimeList = voOrdersProductMapper.selectOrdersTime(ProcuredOrders.getOrdersId(), numbers.get(i));
                                    for (VoOrdersTime voOrdersTime : voOrdersTimeList) {
                                        procuredOrdersMapper.updateOrdersProductSelectedStatus(
                                                (VoOrdersProduct.getStorageNumber() >= voOrdersTime.getNotStockedNumber()) ? Constants.FAIL : Constants.SUCCESS,
                                                ProcuredOrders.getOrdersId(),
                                                VoOrdersProduct.getProductProNo()
                                        );
                                        if (VoOrdersProduct.getStorageNumber()<=voOrdersTime.getNotStockedNumber()) {
                                            inboundProducts.setTertullianProductsNumber(VoOrdersProduct.getStorageNumber());
                                            inboundProducts.setTertullianProductsAmount(VoOrdersProduct.getProductPrice().multiply(BigDecimal.valueOf(VoOrdersProduct.getStorageNumber())));
                                            inboundProducts.setProductsAmount(VoOrdersProduct.getProductPrice().multiply(BigDecimal.valueOf(VoOrdersProduct.getStorageNumber())));
                                            inboundProducts.setProductId(VoOrdersProduct.getProductId());
                                            inboundProducts.setOrdersId(ProcuredOrders.getOrdersId());
                                            inboundProducts.setSubProductId(voOrdersProductMapper.selectSubProductId(ProcuredOrders.getOrdersId(), inboundProducts.getProductId()));
                                            inboundProducts.setSubProductsNumber(Constants.INITIALIZE);
                                            inboundProducts.setSubProductsAmount(BigDecimal.valueOf(0));
                                            inboundProducts.setDeleteStatus(Constants.SUCCESS);
                                            inboundProducts.setAddTime(DateUtils.getNowDate());
                                            sum[0] = sum[0] + VoOrdersProduct.getStorageNumber();
                                            VoOrdersProduct.setStorageNumber(Constants.INITIALIZE);
                                            return inboundProducts;
                                        }else{
                                            sum[0] = sum[0] + voOrdersTime.getNotStockedNumber();
                                            inboundProducts.setTertullianProductsNumber(voOrdersTime.getNotStockedNumber());
                                            inboundProducts.setTertullianProductsAmount(VoOrdersProduct.getProductPrice().multiply(BigDecimal.valueOf(voOrdersTime.getNotStockedNumber())));
                                            inboundProducts.setProductsAmount(VoOrdersProduct.getProductPrice().multiply(BigDecimal.valueOf(voOrdersTime.getNotStockedNumber())));
                                            inboundProducts.setProductId(VoOrdersProduct.getProductId());
                                            inboundProducts.setOrdersId(ProcuredOrders.getOrdersId());
                                            inboundProducts.setSubProductId(voOrdersProductMapper.selectSubProductId(ProcuredOrders.getOrdersId(), inboundProducts.getProductId()));
                                            VoOrdersProduct.setStorageNumber(VoOrdersProduct.getStorageNumber()-voOrdersTime.getNotStockedNumber());
                                            inboundProducts.setSubProductsNumber(Constants.INITIALIZE);
                                            inboundProducts.setSubProductsAmount(BigDecimal.valueOf(0));
                                            inboundProducts.setDeleteStatus(Constants.SUCCESS);
                                            inboundProducts.setAddTime(DateUtils.getNowDate());
                                            return inboundProducts;
                                        }
                                }

                                }
                                return inboundProducts;
                            })
                            .filter(inboundProducts -> Optional.ofNullable(inboundProducts).map(InboundProducts::getTertullianProductsNumber).orElse(0L) != 0)
                            .collect(Collectors.toList());

                    if (newCollect.isEmpty()) {
                        return null; // 如果newCollect为空，则返回null
                    }
                    procuredStorage.setInboundProductsList(newCollect);
                    procuredStorage.setStorageNumber(generateCode(index.getAndIncrement()));
                    procuredStorage.setOrdersId(ProcuredOrders.getOrdersId());
                    procuredStorage.setDepositor(nickName);
//                    procuredStorage.setInboundNumber(sum[0]);
                    procuredStorage.setInboundTime(DateUtils.getNowDate());
//                    procuredStorage.setInboundStatus(Constants.STATUS_TOW);
                    String storageRemark = "采购订单批量入库." + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"));
                    procuredStorage.setStorageRemark(storageRemark);
                    procuredStorage.setUpdateTime(DateUtils.getNowDate());
//                    procuredStorage.setDeleteStatus(Constants.SUCCESS);
                    voOrdersProductMapper.updateOrdersProductNotStockedNumber(newCollect);
                    return procuredStorage;
                })
                .filter(Objects::nonNull) // 过滤掉为null的数据
                .collect(Collectors.toList());
        int rows = procuredStorageMapper.insertProcuredStorage(collect);
        for (ProcuredStorage procuredStorage:collect) {
            insertInboundProducts(procuredStorage);
        }
        return rows;
    }

    @Override
    public List<VoOrdersProduct> selectByIds(Long[] ids) {
        List<VoOrdersProduct> list = voOrdersProductMapper.selectByIds(ids);
        //voOrdersProductMapper.updateByIdDetailsStatus(ids, Constants.FAIL);
        return list;
    }

    @Override
    public int updateDetailsStatus(List<VoOrdersProduct> voOrdersProductList) {
        return voOrdersProductMapper.updateDetailsStatus(voOrdersProductList);
    }

    @Override
    public List<VoOrdersProduct> selectListProductId(Long ordersId) {
        return voOrdersProductMapper.selectListProductId(ordersId);
    }

    @Override
    public int updateProductIdDetailsStatus(Long id) {
        return voOrdersProductMapper.updateProductIdDetailsStatus(id);
    }

    @Override
    public int updateTestDetailsStatus(boolean flay,Long ordersId, Long productId) {
        String status = flay ? Constants.FAIL : Constants.SUCCESS;
        return voOrdersProductMapper.updateTestDetailsStatus(status, ordersId, productId);
    }

    @Override
    public List<SelectedOrderVO> selectByReceiptOrdersIdList(Long[] ordersIds) {
        // 1. 查询所有 VO
        List<SelectedOrderVO> vos = voOrdersProductMapper
                .selectByReceiptOrdersIdList(ordersIds);

        // 2. 扁平化、去重，拿到所有要查图片的 productId
        Set<Long> productIds = vos.stream()
                .flatMap(vo -> vo.getDtoReceiptProductsList().stream())
                .map(VoOrdersProduct::getProductId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());

        if (!productIds.isEmpty()) {
            // 3. 一次性批量查图片，并按 productId 分组，提取 imagePath 列表
            Map<Integer, List<String>> imageMap = productImageMapper
                    .selectProductImagesByProductId(new ArrayList<>(productIds))
                    .stream()
                    .collect(Collectors.groupingBy(
                            ProductImage::getProductId,
                            Collectors.mapping(ProductImage::getProductImagePath,
                                    Collectors.toList())
                    ));

            // 4. 直接遍历所有 VO 的所有产品，给每个 VoOrdersProduct 赋图
            vos.forEach(vo -> vo.getDtoReceiptProductsList().forEach(p -> {
                List<String> imgs = imageMap.get(p.getProductId().intValue());
                // 如果没查到图片，给个空列表或者 null
                p.setImgName(imgs != null ? imgs : Collections.emptyList());
            }));
        }

        return vos;
    }


    /**
     * 新增入库产品信息
     *
     * @param procuredStorage 采购入库单对象
     */
    public void insertInboundProducts(ProcuredStorage procuredStorage)
    {
        List<InboundProducts> inboundProductsList = procuredStorage.getInboundProductsList();
//        Long storageId = procuredStorage.getStorageId();
        if (StringUtils.isNotNull(inboundProductsList))
        {
            List<InboundProducts> list = new ArrayList<InboundProducts>();
            for (InboundProducts inboundProducts : inboundProductsList)
            {
//                inboundProducts.setStorageId(storageId);
                list.add(inboundProducts);
            }
            if (list.size() > 0)
            {
                procuredStorageMapper.batchInboundProducts(list);
            }
        }
    }

    /**
     * 生成随机数
     * @param size
     * @return
     */
    private String generateCode(int size){
        // 获取当前日期
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        String currentDate = dateFormat.format(new Date());

        // 获取序列号
        String storageNumber = voOrdersProductMapper.selectStorageNumber();
        String number;
        // ...根据自己的业务逻辑实现获取序列号的方法
        if(StringUtils.isEmpty(storageNumber)){
//            number = Constants.INBOUND_NUMBER;
            number = String.format("%04d", (NumberUtils.parseNumber(Constants.INBOUND_NUMBER,Long.class)+(size)));
        }else{
            number = String.format("%04d", (NumberUtils.parseNumber(storageNumber.substring(10),Long.class)+(size+1)));
        }
        // 拼接生成的代码
        String code = Constants.STORAGE + currentDate + number;
        return code;
    }


    /**
     * 将["1,2","3,4"]转换为["1","2","3","4"]
     * @param array
     * @return
     */
    private String[] converter(String[] array){
        String[] result = Arrays.stream(array)
                .flatMap(s -> Arrays.stream(s.split(",")))
                .toArray(String[]::new);
        return result;
    }
}
